package org.ands.apps;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

import java.util.Properties;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;

import org.xml.sax.SAXException;

public class TransformXML {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		if (args.length != 1){
			System.err.println("Requires valid path and file to properties file, e.g: java -jar TransformValidateXml.jar ./TransformerConfig.properties");
			System.exit(0);
		}
		
		final String configFilename = args[0];
		if((configFilename == null) || (configFilename.isEmpty())){
			System.err.println("Requires valid config file");
			System.exit(0);
		}
		
		
		

		System.out.println("Reading values from "+configFilename);
			
		try {
			
			FileInputStream in = new FileInputStream(configFilename);
			
			Properties properties = new Properties();
			properties.load(in);
			in.close();
			
			PropertyHelper propertyHelper = new PropertyHelper(properties);
			assert(propertyHelper != null);
			
			String xmlInFileName = propertyHelper.getProperty("XML_IN_FILE", true/*required*/);
			
			String xmlOutFileName = propertyHelper.getProperty("XML_OUT_FILE", true/*required*/);
			
			String xslFileName = propertyHelper.getProperty("XSL_FILE", true/*required*/);
			
			String xsdFileName = propertyHelper.getProperty("XSD_FILE", true/*required*/);
			
			String parser = propertyHelper.getProperty("PARSER", true/*required*/);
			
			System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
			
			transform (xmlInFileName, xslFileName, xmlOutFileName);
			
			URL xsdFileUrl = new URL(xsdFileName);
			
			validate(xmlOutFileName, xsdFileUrl);
			
			System.out.println("See xml output in file "+xmlOutFileName);
			
		} catch (Exception e) {
			System.err.println("Exception ["+e.getMessage()+"].");
			e.printStackTrace();
		}
		
		
	}
	
	public static void transform (final String xmlFileName, final String xslInFileName, final String xmlOutFileName)
		throws 
			TransformerException, 
			TransformerConfigurationException, 
			FileNotFoundException {
		
				File xmlOutFile = new File(xmlOutFileName);
	
		        TransformerFactory factory = TransformerFactory.newInstance();
		        Transformer transformer = factory.newTransformer(new StreamSource(new File(xslInFileName)));
		        transformer.transform(new StreamSource(new File(xmlFileName)),
		        		new StreamResult(new FileOutputStream(xmlOutFile)));
		        
	}
	
	public static void validate (final String xmlFileName, final URL xsdFileUrl) throws SAXException, IOException
	{
		
		Source xmlSource = new StreamSource(new File(xmlFileName));
		SchemaFactory schemaFactory = SchemaFactory
			    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema schema = schemaFactory.newSchema(xsdFileUrl);
			Validator validator = schema.newValidator();
			try {
			  validator.validate(xmlSource);
			  System.out.println(xmlSource.getSystemId() + " is valid");
			} catch (SAXException e) {
			  System.out.println(xmlSource.getSystemId() + " is NOT valid");
			  System.out.println("Reason: " + e.getLocalizedMessage());
			}
	}

}
